package com.ds.core.support.qiniu;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.processing.OperationManager;
import com.qiniu.processing.OperationStatus;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.BatchStatus;
import com.qiniu.util.Auth;
import com.qiniu.util.UrlSafeBase64;

public class Batch {
	/**
	 * 批量获取文件状态
	 * @param zone
	 * @param auth
	 * @param keyList 文件名列表， 单次批量请求的文件数量不得超过1000
	 * @param bucket
	 * @return
	 */
	public static BatchStatus[] getFilesStat(Zone zone,Auth auth,String[] keyList,String bucket) {
		// 构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
			BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
			batchOperations.addStatOps(bucket, keyList);
			Response response = bucketManager.batch(batchOperations);
			BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
			for (int i = 0; i < keyList.length; i++) {
				BatchStatus status = batchStatusList[i];
				String key = keyList[i];
				System.out.print(key + "\t");
				if (status.code == 200) {
					// 文件存在
					System.out.println(status.data.hash);
					System.out.println(status.data.mimeType);
					System.out.println(status.data.fsize);
					System.out.println(status.data.putTime);
				} else {
					System.out.println(status.data.error);
				}
			}
			return batchStatusList;
		} catch (QiniuException ex) {
			System.err.println(ex.response.toString());
		}
		return null;
	}

	/**
	 * 批量修改文件类型，单次批量请求的文件数量不得超过1000
	 * @param zone
	 * @param auth
	 * @param keyMimeMap  文件名：目的类型 ，例keyMimeMap.put("qiniu.jpg", "image/jpg");
	 * @param bucket
	 * @return
	 */
	public static BatchStatus[] editFilesType(Zone zone,Auth auth,HashMap<String, String> keyMimeMap,String bucket) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
		    //添加指令
		    for (Map.Entry<String, String> entry : keyMimeMap.entrySet()) {
		        String key = entry.getKey();
		        String newMimeType = entry.getValue();
		        batchOperations.addChgmOp(bucket, key, newMimeType);
		    }
		    Response response = bucketManager.batch(batchOperations);
		    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
		    int index = 0;
		    for (Map.Entry<String, String> entry : keyMimeMap.entrySet()) {
		        String key = entry.getKey();
		        System.out.print(key + "\t");
		        BatchStatus status = batchStatusList[index];
		        if (status.code == 200) {
		            System.out.println("change mime success");
		        } else {
		            System.out.println(status.data.error);
		        }
		        index += 1;
		    }
		    return batchStatusList;
		} catch (QiniuException ex) {
		    System.err.println(ex.response.toString());
		}
		return null;
	}

	/**
	 * 批量删除文件
	 * @param zone
	 * @param auth
	 * @param keyList 文件名列表， 单次批量请求的文件数量不得超过1000
	 * @param bucket
	 * @return
	 */
	public static BatchStatus[] deleteFiles(Zone zone,Auth auth,String[] keyList,String bucket) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    //单次批量请求的文件数量不得超过1000
		    BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
		    batchOperations.addDeleteOp(bucket, keyList);
		    Response response = bucketManager.batch(batchOperations);
		    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
		    for (int i = 0; i < keyList.length; i++) {
		        BatchStatus status = batchStatusList[i];
		        String key = keyList[i];
		        System.out.print(key + "\t");
		        if (status.code == 200) {
		            System.out.println("delete success");
		        } else {
		            System.out.println(status.data.error);
		        }
		    }
		    return batchStatusList;
		} catch (QiniuException ex) {
		    System.err.println(ex.response.toString());
		    return null;
		}
	}

	/**
	 * 批量移动文件，可用作重命名
	 * @param zone
	 * @param auth
	 * @param opts 操作集合
	 * @return
	 */
	public static BatchStatus[] moveOrRenameFiles(Zone zone,Auth auth,List<OptInfo> opts) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    //单次批量请求的文件数量不得超过1000
		    BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
		    for (OptInfo opt : opts) {
		        batchOperations.addMoveOp(opt.getFromBucket(), opt.getFromKey(), opt.getToBucket(), opt.getToKey());
		    }
		    Response response = bucketManager.batch(batchOperations);
		    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
		    for (int i = 0; i < opts.size(); i++) {
		        BatchStatus status = batchStatusList[i];
		        String key = opts.get(i).getFromKey();
		        System.out.print(key + "\t");
		        if (status.code == 200) {
		            System.out.println("move success");
		        } else {
		            System.out.println(status.data.error);
		        }
		    }
		    return batchStatusList;
		} catch (QiniuException ex) {
		    System.err.println(ex.response.toString());
		}
		return null;
	}

	/**
	 * 批量复制
	 * @param zone
	 * @param auth
	 * @param opts 操作集合
	 * @return
	 */
	public static BatchStatus[] copyFiles(Zone zone,Auth auth,List<OptInfo> opts) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
		    for (OptInfo opt : opts) {
		        batchOperations.addCopyOp(opt.getFromBucket(), opt.getFromKey(), opt.getToBucket(), opt.getToKey());
		    }
		    Response response = bucketManager.batch(batchOperations);
		    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
		    for (int i = 0; i < opts.size(); i++) {
		        BatchStatus status = batchStatusList[i];
		        String key = opts.get(i).getFromKey();
		        System.out.print(key + "\t");
		        if (status.code == 200) {
		            System.out.println("copy success");
		        } else {
		            System.out.println(status.data.error);
		        }
		    }
		    return batchStatusList;
		} catch (QiniuException ex) {
		    System.err.println(ex.response.toString());
		}
		return null;
	}

	/**
	 * 混合批量操作，单次批量请求的文件数量不得超过1000
	 * @param zone
	 * @param auth
	 * @param batchOperations 批量指令集
	 * 		例batchOperations.addStatOps(bucket, "qiniu.png", "qiniu.jpg");
	 *		  batchOperations.addCopyOp(bucket, "qiniu.png", bucket, "qiniu_copy1.png");
	 *		  batchOperations.addMoveOp(bucket, "qiniu2.png", bucket, "qiniu3.png");
	 *		  batchOperations.addDeleteOp(bucket, "qiniu4.png");
	 * @return
	 */
	public static BatchStatus[] fixOpts(Zone zone,Auth auth,BucketManager.BatchOperations batchOperations) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    Response response = bucketManager.batch(batchOperations);
		    BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
		    for (BatchStatus status : batchStatusList) {
		        if (status.code == 200) {
		            System.out.println("operation success");
		        } else {
		            System.out.println(status.data.error);
		        }
		    }
		    return batchStatusList;
		} catch (QiniuException ex) {
		    System.err.println(ex.response.toString());
		}
		return null;
	}

	/**
	 * 镜像空间更新同步
	 * @param zone
	 * @param auth
	 * @param bucket
	 * @param key
	 */
	public static void prefetch(Zone zone,Auth auth,String bucket,String key) {
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(zone);
		BucketManager bucketManager = new BucketManager(auth, cfg);
		try {
		    bucketManager.prefetch(bucket, key);
		} catch (QiniuException ex) {
		    //如果遇到异常，说明更新失败
		    System.err.println(ex.code());
		    System.err.println(ex.response.toString());
		}
	}

	public static void persistence(Auth auth,String bucket,String key) {
		//数据处理指令，支持多个指令
		String saveMp4Entry = String.format("%s:avthumb_test_target.mp4", bucket);
		String saveJpgEntry = String.format("%s:vframe_test_target.jpg", bucket);
		String avthumbMp4Fop = String.format("avthumb/mp4|saveas/%s", UrlSafeBase64.encodeToString(saveMp4Entry));
		String vframeJpgFop = String.format("vframe/jpg/offset/1|saveas/%s", UrlSafeBase64.encodeToString(saveJpgEntry));
		//将多个数据处理指令拼接起来
		String persistentOpfs = StringUtils.join(new String[]{
		        avthumbMp4Fop, vframeJpgFop
		}, ";");
		//数据处理队列名称，必须
		String persistentPipeline = "mps-pipe1";
		//数据处理完成结果通知地址
		String persistentNotifyUrl = "http://api.example.com/qiniu/pfop/notify";
		//构造一个带指定Zone对象的配置类
		Configuration cfg = new Configuration(Zone.zone0());
		//...其他参数参考类注释
		//构建持久化数据处理对象
		OperationManager operationManager = new OperationManager(auth, cfg);
		try {
		    String persistentId = operationManager.pfop(bucket, key, persistentOpfs, persistentPipeline, persistentNotifyUrl, true);
		    //可以根据该 persistentId 查询任务处理进度
		    System.out.println(persistentId);
		    OperationStatus operationStatus = operationManager.prefop(persistentId);
		    //解析 operationStatus 的结果
		} catch (QiniuException e) {
		    System.err.println(e.response.toString());
		}
		//OperationStatus operationStatus = operationManager.prefop(persistentId);
		//解析 operationStatus 的结果
	}

	public static void main(String[] args) {
		Zone zone=Zone.zone0();
		Auth auth=CredentialsManager.getAuth();
		String bucket="ds-literary";
		
//		//测试getFilesStat
//		getFilesStat(zone, auth, new String[]{"2.jpg","3.jpg","4.jpg","noFile.jpg"},bucket);
//		
//		//测试editFilesType
//		HashMap<String,String> keyMimeMap =new HashMap<>();
//		keyMimeMap. put("2.jpg", "text/plain");
//		keyMimeMap. put("4.jpg", "text/plain");
//		editFilesType(zone, auth, keyMimeMap, bucket);
//		
//		//测试deleteFiles
//		deleteFiles(zone, auth, new String[]{"5.jpg","3.jpg","noFile.jpg"}, bucket);
//		
//		//测试moveOrRenameFiles
//		List<OptInfo> opts=new ArrayList<>();
//		opts.add(new OptInfo(bucket, "as.txt", "bucket2", "as.txt"));
//		opts.add(new OptInfo(bucket, "sa.txt", "bucket2", "as.txt"));
//		moveOrRenameFiles(zone, auth, opts);
//		
//		//测试copyFiles
//		List<OptInfo> opts2=new ArrayList<>();
//		opts2.add(new OptInfo(bucket, "fff.txt", "bucket2", "fff.txt"));
//		opts2.add(new OptInfo(bucket, "ggg.txt", "bucket2", "ggg.txt"));
//		copyFiles(zone, auth, opts2);
//		
//		//测试fixOpts
//		BatchOperations batchOperations=new BatchOperations();
//		batchOperations.addDeleteOp(bucket, new String[]{"15.jpg","13.jpg","noFile.jpg"});
//		batchOperations.addCopyOp(bucket, "mmm.txt", "bucket2", "mmm.txt");
//		fixOpts(zone, auth, batchOperations);
		
		//测试prefetch
		prefetch(zone, auth, bucket, "FuWyOfil3ZgwGnBANuHJ265ubed2");
	}
}
